import CryptoJS from 'crypto-js'

export default {
  /**
   * 随机生成指定数量的32进制key
   * @param num 生成密钥位数，默认16位
   * @return {string}
   */
  generatekey (num) {
    num = num || 16
    const library = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
    let key = ''
    for (let i = 0; i < num; i++) {
      const randomPoz = Math.floor(Math.random() * library.length)
      key += library.substring(randomPoz, randomPoz + 1)
    }
    return key
  },
  /**
   * 加密，传了盐度值就是CBC模式，没传就是ECB模式
   * @param word 待加密的内容
   * @param keyStr 密钥
   * @param ivStr 偏移量，盐度值
   * @return 加密结果
   */
  encrypt (word, keyStr, ivStr) {
    // 判断是否存在keyStr，不存在就用默认的keyStr（注意：这个keyStr必需要前后端统一，不然双方加密解密后会不相同。调用generatekey方法生成）
    keyStr = keyStr || '1grLx91U40VawzhRAm7E'
    const key = CryptoJS.enc.Utf8.parse(keyStr)
    const srcs = CryptoJS.enc.Utf8.parse(word)
    let encrypted = ''
    if (ivStr) {
      // CBC是工作模式 Pkcs7是填充模式
      const iv = CryptoJS.enc.Utf8.parse(ivStr)
      encrypted = CryptoJS.AES.encrypt(srcs, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      })
      return encrypted.toString()
    } else {
      // ECB是工作模式 Pkcs7是填充模式
      encrypted = CryptoJS.AES.encrypt(srcs, key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
      })
      return encrypted.toString()
    }
  },
  /**
   * 解密，传了盐度值就是CBC模式，没传就是ECB模式
   * @param word 待解密的内容
   * @param keyStr 密钥
   * @param ivStr 偏移量，盐度值
   * @return 解密结果
   */
  decrypt (word, keyStr, ivStr) {
    keyStr = keyStr || '1grLx91U40VawzhRAm7E'
    const key = CryptoJS.enc.Utf8.parse(keyStr)
    let decrypt = ''
    if (ivStr) {
      // CBC
      const iv = CryptoJS.enc.Utf8.parse(ivStr)
      decrypt = CryptoJS.AES.decrypt(word, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      })
      return decrypt.toString(CryptoJS.enc.Utf8)
    } else {
      // EBC
      decrypt = CryptoJS.AES.decrypt(word, key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
      })
      return CryptoJS.enc.Utf8.stringify(decrypt).toString()
    }
  }
}
